<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Design by Free CSS Templates
http://www.freecsstemplates.org
Released for free under a Creative Commons Attribution 2.5 License
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>CSC560 Design and Analysis of Real-Time Systems</title>
<meta name="keywords" content="CSC560" />
<meta name="description" content="CSC560" />
<link href="../default.css" rel="stylesheet" type="text/css" />

<!-- Needed for SOURCE CODE SAMPLES -->
<script type="text/javascript" src="../scripts/shCore.js"></script>
<script type="text/javascript" src="../scripts/shBrushBash.js"></script>
<script type="text/javascript" src="../scripts/shBrushCpp.js"></script>
<link type="text/css" rel="stylesheet" href="../styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="../styles/shThemeDefault.css"/>
<script type="text/javascript">
	SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';
	SyntaxHighlighter.all();
</script>
<!-- End of Needed for SOURCE CODE SAMPLES -->

</head>
<body>
<div id="wrapper">
	<div id="header">
		<h1>CSC560</h1>
		<h2>Design and Analysis of Real-Time Systems</h2>
		<ul>
			<li class="first"> <a href="../index.html" accesskey="1" title="">Home</a> </li>
			<li> <a href="../project1/index.html" accesskey="2" title="">Project 1</a>	</li>
			<li> <a href="../project2/index.html" accesskey="3" title="">Project 2</a> </li>
			<li> <a href="../project3/index.html" accesskey="4" title="">Project 3</a> </li>
			<li> <a href="../project4/index.html" accesskey="4" title="">Project 4</a> </li>
			<li> <a href="index.html" accesskey="4" title=""><b>Project 5</b></a> </li>
		</ul>
	</div>
</div>
<div id="content">
	<div id="colOne">
		<h2>Implementation Approach</h2>
		<p>
			This section describes the implementation approach we have used in order to build a working system.
			We present simple source code implementation that shows how we made certain parts of the system work 
			correctly. The code of the entire system has been done by integrating parts of the code described 
			here and is more elaborated. Hopefully, this
			section will be useful for future students who would like to build a system similar to ours. The code 
			can be found in the Google Code project section.
		</p> 
		<p>
			First, we have decided to breakdown the implementation in several parts. The reason for doing this is
			that some parts of the implementation are crucial to the system. Our strategy is to first implement
			areas of uncertainties so that we know whether we will succeed at building the proposed system or if 
			we need to make modification early in the implementation process. For example, the IR Beacons are 
			essential for the game to work properly. Without the IR beacons, it would be difficult to 
			implement the <i>chasing</i> and <i>escaping</i> modes since the accuracy and appropriateness of these modes heavily rely 
			on the IR beacons. A second important part of the system is the communication between the two roombas. Without
			communication, the game cannot start, and roombas cannot communicate their state to each other. Therefore,
			in this section we are presenting test code of parts of the system, and discuss how it was implemented.
			
		</p>
		<h3>Discussion of code</h3>
		<p>
		<ul>
				<li> 
				1. Code to test the IR Beacons
				</li>
				<li> 
				2. Code to test AT90USBKey movement to Roomba command.
				</li>
				<li> 
				3. Code to detect bumper status.
				</li>
				<li>
				4. Code to let the cat do "intelligent" moves to hit the front bumper of the mouse.
				</li>
				
		</ul>
		</p>
		<h3>1. Code to test the IR Beacons</h3>
		<p>
			The first part of the implementation is to write code that tells us when a beacon detects infrared light.
			In the following piece of code, when the north beacon detects an infrared light, the red LED on PORTD4 is turned
			on. The following diagram shows how we connected the beacon to the AT90USBKey. Anyone who would like to reproduce
			this example should closely follow this example.
		</p>
		<h4>Pin Diagram</h4>
		<a href ="images/IRBeacon_AT90.jpg"><img src="images/IRBeacon_AT90.jpg"/> </a>
		<br><br>
		<h4>Snippet of Code</h4>
		<pre class="brush: c;">
		#include &lt;stdlib.h&gt;
		#include &lt;util/delay.h&gt;
		#include &lt;avr/io.h&gt;
		
		/** Get North sensor reading.
		 *  @return 1 if the North sensor detects an IR signal, 0 if it does not.
		 */
		uint8_t get_IR_North()
		{
			// if the N pin is low, then the north sensor sees an IR signal
			return (PINA & _BV(PORTA7)) == 0;
		}
		
		int main(void) {
			//initialize Beacon, set IR pins to input (DDR = 0bx0x0x0x0)
			DDRA &= ~(_BV(PORTA7) | _BV(PORTA5) | _BV(PORTA3) | _BV(PORTA1));
			PORTA |= (_BV(PORTA7) | _BV(PORTA5) | _BV(PORTA3) | _BV(PORTA1));
		
			//initialize leds
			DDRD = (1&lt;&lt;PORTD4);
		
			for (;;) {
				if (get_IR_North() == 1) {
					PORTD ^= _BV(PORTD4);
				}
				else {
					PORTD &= 0x00;
				}
			}
		}
		</pre>
		<h4>Code Explanation</h4><br>
		In lines from 8 to 12, we implemented a function that polls the north sensor to check whether the pin is set to low. If the pin is low, 
		this means the north sensor has detected an infrared signal. Actually, according to the IR Beacon specification, only one sensor pin 
		can be low at any time, and it is the one that detects the strongest signal.<br><br>
		
		The main program starts by initializing the pins on the AT90USBKey that are connected to the IR Beacon as input on line 16 and 17.
		Line 20 initializes the pin for the LED and line 23 to 28 is a conditional statement that turn on LED on PORTD4 if the north sensor 
		detects an infrared light, otherwise the LED is turned off.
		
		<br><br>
		The following video shows the result of a similar piece of code where the cat locates the mouse with the IR beacon and then execute
		sci commands to move towards the mouse. In this video, lines 23 to 27 have been replaced with code that execute a movement command
		in the direction where the sensor is active low.
		<br><br><br>
		<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/GO1X928JsAU&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/GO1X928JsAU&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"></embed></object>
		
		<br>
		<br>
		<h3>2. Code to test AT90USBKey movement to Roomba command</h3> 
		<p>
			Next, we wrote code to send a driving command to the roomba.
			We have done something similar in project 1 and 2. However, the command was sent from a base station 
			to a remote station and was then forwarded to the roomba. 
			<br>
			We have used Neil's code to accomplish this task. The following shows a minimal example on how to drive
			the roomba from the AT90USBKey.
		</p>
		<h4>Snippet of Code</h4>
		<pre class="brush: c;">
#include "roomba/roomba.h"
#include "roomba/roomba_sci.h"
#include "uart/uart.h"
#include &lt;util/delay.h&gt;

/**
 * Commands to drive the roomba at a certain velocity and radius
 */
void roomba_Drive( int16_t velocity, int16_t radius )
{
	uart_putchar(DRIVE);
	uart_putchar(HIGH_BYTE(velocity));
	uart_putchar(LOW_BYTE(velocity));
	uart_putchar(HIGH_BYTE(radius));
	uart_putchar(LOW_BYTE(radius));
}

int main()
{
	Roomba_Init();

	//drive roomba straight
	roomba_Drive(100, 0x8000);

	//delay for 1 s
	_delay_ms(1000);

	//stop roomba
	roomba_Drive(0, 0);

	for (;;);
}

		</pre>
		<h4>Code Explanation</h4><br>
		Line 1 to 3 import essential function headers necessary to initialize the roomba and send driving commands to the roomba.
		Line 4 imports the function headers necessary for inserting delay in the code.
		Line 6 to 16 declares a function that send a command to the roomba. The parameters passed are a velocity and a radius.
		Line 20 calls the function to initialize the roomba. Lines 22 to 29 calls the roomba_Drive function to drive the roomba at 100mm/s forward
		for about 1 second and then sends another command to stop the roomba.
		<br>
		

		
		<br>
		<br>
		<h3>3. Code to detect bumper status</h3> 
		<p>
			One of the requirements of the game is to retrieve the status of the bumper to find out if the cat has
			bumped into the mouse. In order to get the bumper status, we must look at the Roomba Specification 
			Documentation Manual in order to understand how to retrieve information from the roomba. 
			The roomba can return sensor data in response to a sensor command. Sensor data
			examples are bumper status, distance, charging state, etc... The roomba will send one to four different sensor
			data packets in response to a sensor command. A value of 0 sends all of the data bytes, a value of 1 sends 
			information about external sensors, a value of 2 sends information about chassis sensors, and a value of 3
			sends information about internal sensors. The bumper information is available in the external sensors, so 
			we will want to ask the roomba to send us this information.
			The following code shows how we achieved this.
		</p>
		<h4>Snippet of Code</h4>
		<pre class="brush: c;">
#include "../header/common.h"
#include "../roomba/roomba.h"
#include "../roomba/roomba_sci.h"
#include "../uart/uart.h"
#include &lt;util/delay.h&gt;

#define     clock8MHz()    CLKPR = _BV(CLKPCE); CLKPR = 0x00;

int main(void) {

	clock8MHz();

	//initialize leds
	DDRD = (1&lt;&lt;PORTD4) | (1&lt;&lt;PORTD5);

	//initialize roomba
	Roomba_Init();

	//ask for sensor data by sending sensor command
	uart_putchar(SENSORS);
	
	//ask for packet subset 1 which contains external sensor data (bumper status)
	uart_putchar(1);
	
	//receive sensor data
	while (uart_bytes_received() != 1);

	//store bumper information
	uint8_t bumper_status = uart_get_byte(0);

	//if bumper_status is 0, bumper is not activated
	if (bumper_status == 0) {
		//turn on red LED
		PORTD ^= _BV(PD4);
	}
	//else bumper is activated
	else {
		//turn on green LED
		PORTD ^= _BV(PD5);
	}

	return 0;
}
		</pre>
		<h4>Code Explanation</h4><br>
		Lines 1 to 5 import header files given by our TA that are necessary to communicate with the roomba. 
		Line 20 sends a sensor command to the roomba to tell it is requesting for sensor data.
		Line 23 sends 1 to the roomba to tell it is requesting packet subset 1 which contains
		external sensor data such as the bumper status we are interested in. 
		Line 26 receives the first sensor data byte and line 29 assigns the bumper status to a local variable.
		The bumper status is either 0 or 1, 0 if the bumper is not triggered and 1 if it is triggered.
		Line 31 to 40 will turn on the LED to red if the bumper is not triggered and turn on the LED to green
		if triggered. The following video shows an example of testing the bumper.
		<br><br>This video shows that when the bumper is pressed, a green LED is activated. When the bumper is not pressed,
		a red LED is activated.<br><br>
		
		<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/PBxNJW0ZO3Q&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/PBxNJW0ZO3Q&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"></embed></object>
		<br><br><br>
		
		<br>
		<br>
		<h3>4. Code to let the cat do "intelligent" moves to hit the front bumper of the mouse.</h3> 
		<p>
			In the following example, we are testing an implementation approach that we have
			discussed with Dr. Cheng. The idea is that whenenver the cat sees the mouse 
			from the front, it sends a packet to the mouse asking whether it (the mouse) sees
			the cat from the front. If it does, that means the cat and the mouse are facing
			each other and that it is safe to execute a movement command towards the cat.
			We have modified this idea so that the mouse tells the cat from which side 
			it sees the cat. When the cat gets this information, it will execute the 
			appropriate movement command.
		</p>
		<h4>Snippet of Code</h4>
		<br>
		Cat snippet of code:
		<br>
		<pre class="brush: c;">
void search_task(void) {
		...
		//if sensor is north, send packet to mouse
		if (is_sensor_north()) {
					bumper_flag = 1;
					Signal_And_Next(sendEvent);
		}
		...
}		

void radio_rx(void) {
	...
			Radio_Receive(&status_packet);
			
			//mouse sees cat from the front
			if (status_packet.payload.sensors.sensors.wall == 1) {
				//move forward
				roomba_Drive(250, 0x8000);
				...
			}
			//mouse sees the cat from the back
			else if (status_packet.payload.sensors.sensors.wall == 2) {
				//make a slight right turn
				roomba_Drive(50,0xFFFF);
				//drive forward
				roomba_Drive(150, 0x8000);
				...
			}
			//mouse sees the cat from the east
			else if (status_packet.payload.sensors.sensors.wall == 3) {
				//make a slight right turn
				roomba_Drive(50,0xFFFF);
				...
				//drive forward
				roomba_Drive(150,0x8000);
				...
			}
			//mouse sees the cat from the west
			else if (status_packet.payload.sensors.sensors.wall == 4) {
				//make a slight left turn
				roomba_Drive(50,0x0001);
				...
				//drive forward
				roomba_Drive(150,0x8000);
				...
			}
	...
}
		</pre>
		<br>
		Mouse snippet of code:
		<br>		
		<pre class="brush: c;">
void radio_receive_task(void) {
			...
			packet.payload.sensors.sensors.wall = get_sensor_info();
			
			//Transmit packet back
			Radio_Transmit(&packet,RADIO_RETURN_ON_TX);
			...
}
		</pre>
		<h4>Code Explanation</h4><br>
		Line 1 to 59 contains snippet of code of two functions: search, radio_rx. In line 1 to 9, the search function verifies if the north sensor is activated. If so, it
		sends a packet to the mouse. Line 11 shows the start of the radio_rx function. The cat receives a packet from the mouse on line 13. On line 15 to 46, the cat 
		will execute a movement command according to the direction the mouse has detected the cat. For instance, 
		if the mouse sees the cat from the front, the cat will execute a movement towards the north. If the mouse sees the cat from the east, the cat will
		execute a slight turn to the right and then go forward, etc... The snippet of code for the mouse shows that upon receiving a packet, the mouse polls its sensor 
		to know which direction it is sensing the cat.
		<br>
		<br><br>
		The following videos show the result of the implementation.<br><br><br>
		<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Ij9LBKo5uk4&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Ij9LBKo5uk4&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
		<br>The first video shows the cat reaching the mouse from the front. The mouse is facing the cat, so it is fairly easy for the cat.<br><br>
		<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/lMmr3Md1HNo&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/lMmr3Md1HNo&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
		<br>The second video shows the cat reaching the mouse from the front again. The difference is that the mouse is now facing the cat on the east. So the cat has to find a path to reach the mouse from 
		the front.
		<br>The third video shows the cat reaching the mouse when it is facing its back.<br><br>
		<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/MH0PAw8izqQ&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/MH0PAw8izqQ&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
		
	</div>
	<div id="colTwo">
		<h3>Project Sections</h3>
		<ul>
			<li class="first"><a href="01_hardware_description.html">Hardware Description</a></li>
			<li><a href="02_software_design.html">Software Design</a></li>
			<li><a href="03_implementation_approach.html"><b>Implementation Approach</b></a></li>
			<li><a href="04_development_process.html">Development Process</a></li>
			<li><a href="05_doxygen.html">Doxygen</a></li>
			<li><a href="http://code.google.com/p/wireless-roomba">Google Code</a></li>
			<li><a href="07_future_work.html">Future Work</a></li>
		</ul>
	</div>
</div>
<div id="footer">
	<p>
		@ 2009. All Rights Reserved. Design by 
		<a href="http://www.freecsstemplates.org/">Free CSS Templates</a>.
	</p>
</div>
</body>
</html>
